﻿using Bnbjoy.Business.Abstract;
using Bnbjoy.Business.Common;
using Bnbjoy.Business.Concrete;
using Bnbjoy.Business.Model.RoomType;
using Bnbjoy.Domain.Abstract;
using Bnbjoy.Domain.Concrete;
using Bnbjoy.Domain.Entities;
using BnbjoyBackend.Api.Security;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace BnbjoyBackend.Api.Controllers
{
    public class RoomTypeController : ApiController
    {
        [Route("api/roomtype/catalog")]
        [HttpPost]
        [Authorize(Roles = "BA, BE")]
        public async Task<HttpPostResponse> ListRoomTypes([FromBody]QueryAllRoomTypesParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            var bnbId = param.BnbId;
            using (IRoomTypeService roomTypeService = new RoomTypeService(new RoomTypeRepository()))
            {
               var result = await roomTypeService.Catalog(bnbId);
                    
               if (result != null)
               {
                   var resultJson = JsonHelper.ConvertObjectToJson(result);
                   return new HttpPostResponse(HttpStatusCode.OK, resultJson);
               }
               else
               {
                   return new HttpPostResponse(HttpStatusCode.Forbidden, "房型名或房号名重复");
               }
            }
        }

        [Route("api/roomtype/move_up_rank")]
        [HttpPost]
        [Authorize(Roles = "BA, BE")]
        public async Task<HttpPostResponse> MoveUpRank([FromBody]ExchangeRankParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            using (IRoomTypeService roomTypeService = new RoomTypeService(new RoomTypeRepository()))
            {
                bool result = await roomTypeService.MoveUpRank(param.BnbId, param.CurrentRank);
                if (result)
                {
                    return new HttpPostResponse(HttpStatusCode.OK, "房型排名修改成功");
                }
                else 
                {
                    return new HttpPostResponse(HttpStatusCode.InternalServerError, "房型排序修改错误");
                }
            }
        }

        [Route("api/roomtype/move_down_rank")]
        [HttpPost]
        [Authorize(Roles = "BA, BE")]
        public async Task<HttpPostResponse> MoveDownRank([FromBody]ExchangeRankParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            using (IRoomTypeService roomTypeService = new RoomTypeService(new RoomTypeRepository()))
            {
                bool result = await roomTypeService.MoveDownRank(param.BnbId, param.CurrentRank);
                if (result)
                {
                    return new HttpPostResponse(HttpStatusCode.OK, "房型排名修改成功");
                }
                else
                {
                    return new HttpPostResponse(HttpStatusCode.InternalServerError, "房型排序修改错误");
                }
            }
        }

        [Route("api/roomtype/new_room_type")]
        [HttpPost]
        [Authorize(Roles = "BA, BE")]
        public async Task<HttpPostResponse> NewRoomType([FromBody]NewRoomTypeModel param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            var roomTypeId = Guid.NewGuid().ToString("n");
            var roomType = new RoomType
            {
                BnbId = param.BnbId,
                RoomTypeId = roomTypeId,
                RoomTypeName = param.RoomTypeName,
                Notes = param.Notes
            };

            List<Room> rooms = new List<Room>();
            foreach (var newRoom in param.NewRoomList)
            {
                var room = new Room
                {
                    BnbId = param.BnbId,
                    RoomTypeId = roomTypeId,
                    RoomId = Guid.NewGuid().ToString("n"),
                    RoomNumber = newRoom.RoomNumber,
                    Enabled = true
                };

                rooms.Add(room);
            }

            var commonPrice = new CommonPrice 
            {
                 Id = Guid.NewGuid().ToString("n"),
                 InitPrice = param.CommonPrice.InitPrice,
                 MondayPrice = param.CommonPrice.MondayPrice,
                 TuesdayPrice = param.CommonPrice.TuesdayPrice,
                 WednesdayPrice = param.CommonPrice.WednesdayPrice,
                 ThursdayPrice = param.CommonPrice.ThursdayPrice,
                 FridayPrice = param.CommonPrice.FridayPrice,
                 SaturdayPrice = param.CommonPrice.SaturdayPrice,
                 SundayPrice = param.CommonPrice.SundayPrice,
                 RoomTypeId = roomTypeId
            };

            using (IRoomTypeService roomTypeService = new RoomTypeService(new RoomTypeRepository()))
            {
                RoomTypeResponse result = await roomTypeService.NewRoomType(roomType, rooms, commonPrice);
                if (result != null)
                {
                    string resultJson = JsonHelper.ConvertObjectToJson(result);
                    return new HttpPostResponse(HttpStatusCode.OK, resultJson);
                }
                else
                {
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "房型名或房号名重复");
                }
            }
        }

        [Route("api/roomtype/update_daily_price")]
        [HttpPost]
        [Authorize(Roles = "BA, BE")]
        public async Task<HttpPostResponse> UpdateDailyPrice([FromBody]UpdateDailyPriceModel param) 
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            using (IRoomTypeService roomTypeService = new RoomTypeService(new RoomTypeRepository())) 
            {
                var fromDate = DateTime.Parse(param.FromDate);
                var toDate = DateTime.Parse(param.ToDate);

                //验证时间范围
                if (fromDate < DateTime.Now || toDate < fromDate) 
                {
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "设定的时间范围有误");
                }

                if (param.Price < 1) 
                {
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "房价不低于1元");
                }

                if (param.Price > 9999) 
                {
                    return new HttpPostResponse(HttpStatusCode.Forbidden, "房价不超过9999元");
                }

                bool success = await roomTypeService.ModifyDailyPrice(fromDate, toDate, param.RoomTypeId, param.Price);
                if (success)
                {
                    return new HttpPostResponse(HttpStatusCode.OK, "房价修改成功");
                }
                else 
                {
                    return new HttpPostResponse(HttpStatusCode.InternalServerError, "房价修改失败");
                }
            }
        }

        [Route("api/roomtype/list_daily_price")]
        [HttpPost]
        [Authorize(Roles = "BA, BE")]
        public async Task<HttpPostResponse> ListDailyPrices([FromBody]ListDailyPriceParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            using (IRoomTypeService roomTypeService = new RoomTypeService(new RoomTypeRepository()))
            {
                SortedDictionary<int, decimal> priceSd = await roomTypeService.FetchRoomTypeDailyPrice(param.Year, param.Month, param.RoomTypeId);
                var prices = priceSd.Values.ToList();
                if (prices != null && prices.Count > 0)
                {
                    var pricesJson = JsonHelper.ConvertObjectToJson(prices);
                    return new HttpPostResponse(HttpStatusCode.OK, pricesJson);
                }
                else 
                {
                    return new HttpPostResponse(HttpStatusCode.InternalServerError, "获取该月房价列表失败");
                }
            }
        }

        [Route("api/roomtype/list_custom_daily_price")]
        [HttpPost]
        [Authorize(Roles = "BA, BE")]
        public async Task<HttpPostResponse> ListCustomDailyPrices([FromBody]ListCustomDailyPriceParam param)
        {
            if (!ModelState.IsValid)
            {
                var message = string.Join(" | ", ModelState.Values
                              .SelectMany(v => v.Errors)
                              .Select(e => e.ErrorMessage));
                return new HttpPostResponse(HttpStatusCode.BadRequest, message);
            }

            using (IRoomTypeService roomTypeService = new RoomTypeService(new RoomTypeRepository()))
            {
                var fromTime = DateTime.Parse(param.FromTime);
                var toTime = DateTime.Parse(param.ToTime);

                SortedDictionary<string, decimal> priceSd = await roomTypeService.FetchCustomRoomTypeDailyPrice(fromTime, toTime, param.RoomTypeId);
                var prices = priceSd.Values.ToList();
                if (prices != null && prices.Count > 0)
                {
                    var pricesJson = JsonHelper.ConvertObjectToJson(prices);
                    return new HttpPostResponse(HttpStatusCode.OK, pricesJson);
                }
                else
                {
                    return new HttpPostResponse(HttpStatusCode.InternalServerError, "获取该时段房价列表失败");
                }
            }
        }

    }
}
